#pragma once
#include <iostream>
#include <string>
#include <mutex>
#include <thread>
#include <ctime>
#include <memory>
#include <cstdarg>
#include <cstdio>
#include <fstream>
#include <functional>
#include <cstdint>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <cstring>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <cstdlib>
#include <vector>
#include <pthread.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <unordered_map>
#include <sys/timerfd.h>
#include <sys/eventfd.h>
#include "../Any.hpp"
/*-----------------------------------------------------------------------------*/
// 日志
// 日志等级和打印模式
const std::string DEFAULTSTR = "Log.txt";
enum
{
    DEBUG = 1,
    INFO,
    WARNING,
    ERROR,
    FATAL,
    _SCREEN_TYPE_,
    _FILE_TYPE
};
struct Logmessage
{
    std::string _level; // 等级
    pid_t _pid;
    std::string _filename;   // 文件名
    int _filenumber;         // 行号
    std::string _curr_time;  // 获取日志信息出现的时间
    std::string _logmessage; // 信息
};

std::string LevelToString(int level)
{
    switch (level)
    {
    case DEBUG:
        return "DEBUG";
        break;
    case INFO:
        return "INFO";
        break;
    case WARNING:
        return "WARNING";
        break;
    case ERROR:
        return "ERROR";
        break;
    case FATAL:
        return "FATAL";
        break;
    default:
        return "UNKNOW";
        break;
    }
}
std::string GetCurrTime()
{
    time_t now_time = time(nullptr);
    struct tm *curr_time = localtime(&now_time);
    // 转换为string格式
    char buf[128];
    snprintf(buf, sizeof(buf), "%d-%02d-%02d %02d:%02d:%02d",
             curr_time->tm_year + 1900, curr_time->tm_mon + 1, curr_time->tm_mday, curr_time->tm_hour, curr_time->tm_min, curr_time->tm_sec);
    return buf;
}
class Log
{
    void LogMsgToScreen(const Logmessage &logmsg)
    {
        printf("[%s][%d][%s][%d][%s] %s",
               logmsg._level.c_str(),
               logmsg._pid, logmsg._filename.c_str(),
               logmsg._filenumber,
               logmsg._curr_time.c_str(),
               logmsg._logmessage.c_str());
    }
    void LogMsgToFile(const Logmessage &logmsg)
    {
        char buf_info[2048] = "\0";
        snprintf(buf_info, sizeof(buf_info), "[%s][%d][%s][%d][%s] %s",
                 logmsg._level.c_str(),
                 logmsg._pid, logmsg._filename.c_str(),
                 logmsg._filenumber, logmsg._curr_time.c_str(),
                 logmsg._logmessage.c_str());
        /*--系统调用版本--*/
        // int fd = open(_logfile.c_str(),O_CREAT | O_WRONLY | O_APPEND,0666);
        // if(fd < 0)
        // {
        //     perror("open");
        //     return;
        // }
        // write(fd,buf_info,sizeof(buf_info));

        /*--c++提供的fstream--*/
        std::ofstream out;
        out.open(_logfile, std::ios::out | std::ios::app | std::ios::binary);
        if (!out.is_open())
            return;
        out.write(buf_info, sizeof(buf_info));
        out.close();
    }
    void FlushLogMsg(int level, const Logmessage &logmsg)
    {
        // c++11的锁
        //  _mutex.lock();
        // RAII类型的锁
        std::unique_lock<std::mutex> lock(_mtx);
        switch (_type)
        {
        case _SCREEN_TYPE_:
            LogMsgToScreen(logmsg);
            break;
        case _FILE_TYPE:
            LogMsgToFile(logmsg);
            break;
        }
    }
    Log(const std::string &logfile = DEFAULTSTR) : _logfile(logfile), _type(_SCREEN_TYPE_)
    {
    }

public:
    Log(const Log &lg) = delete;
    Log(Log &lg) = delete;
    Log(Log &&lg) = delete;
    void ModPrintFormat(int type)
    {
        std::unique_lock<std::mutex> lock(_mtx);
        _type = type;
    }
    void LogMessage(int level, std::string filename, int filenumber, const char *format, ...) // 注意-->可变函数参数
    {
        if (level == DEBUG && _isopen)
            return;
        Logmessage msg;
        msg._level = LevelToString(level);
        msg._filename = filename;
        msg._pid = getpid();
        msg._filenumber = filenumber;
        msg._curr_time = GetCurrTime();
        // 注意：取出可变参数的固定写法
        va_list _ap;           // 创建变量,本质是一个指针
        va_start(_ap, format); // 将参数列表中离...最近的确定的参数传入
        char log_info[512];
        vsnprintf(log_info, sizeof(log_info), format, _ap);
        va_end(_ap); // 销毁_ap
        msg._logmessage = log_info;
        FlushLogMsg(level, msg);
    }
    ~Log()
    {
    }
    void EnableFiltration(bool flag)
    {
        std::unique_lock<std::mutex> lock(_mtx);
        _isopen = flag;
    }
    static Log *GetInstance(const std::string &logfile = DEFAULTSTR)
    {
        // 双重检查锁定模式
        if (_lg == nullptr)
        {
            std::unique_lock<std::mutex> lock(_static_mtx);
            if (_lg == nullptr)
            {
                _lg = new Log(logfile);
            }
        }
        return _lg;
    }

private:
    static Log *_lg;
    int _type;
    std::string _logfile;
    std::mutex _mtx;
    static std::mutex _static_mtx;
    bool _isopen = false;
};

std::mutex Log::_static_mtx;
Log *Log::_lg = nullptr;
static std::unique_ptr<Log> _ptr(Log::GetInstance());
// 打开过滤器
#define EnabelFILTRATION()            \
    do                                \
    {                                 \
        _ptr->EnableFiltration(true); \
    } while (0)
// 关闭过滤器
#define ClOSEFILTRATION                \
    do                                 \
    {                                  \
        _ptr->EnableFiltration(false); \
    } while (0)
#define LOG(level, format, ...)                                             \
    do                                                                      \
    {                                                                       \
        _ptr->LogMessage(level, __FILE__, __LINE__, format, ##__VA_ARGS__); \
    } while (0)

#define LOGTOSCREEN(level, format, ...)                                     \
    do                                                                      \
    {                                                                       \
        _ptr->ModPrintFormat(_SCREEN_TYPE_);                                \
        _ptr->LogMessage(level, __FILE__, __LINE__, format, ##__VA_ARGS__); \
    } while (0)

#define LOGTOFILE(level)                  \
    do                                    \
    {                                     \
        _ptr->ModPrintFormat(_FILE_TYPE); \
    } while (0)
/*-----------------------------------------------------------------------------*/
#define BUFFER_DEFAULT_SIZE 4096
class Buffer
{
private:
    std::vector<char> _buffer; // 使⽤vector进⾏内存空间管理
    uint64_t _reader_idx;      // 读偏移
    uint64_t _writer_idx;      // 写偏移

    char *FindCRLF()
    {
        char *res = (char *)memchr(ReadPosition(), '\n', ReadAbleSize());
        return res;
    }
    // 写入string字符串风格数据
    void WriteString(const std::string &data)
    {
        return Write(data.c_str(), data.size());
    }
    // 确保可写空间⾜够（整体空闲空间够了就移动数据，否则就扩容）
    void EnsureWriteSpace(uint64_t len)
    {
        // 如果末尾空闲空间⼤⼩⾜够，直接返回
        if (TailIdleSize() >= len)
        {
            return;
        }
        // 末尾空闲空间不够，则判断加上起始位置的空闲空间⼤⼩是否⾜够, 够了就将数据移动到起始位置
        if (len <= TailIdleSize() + HeadIdleSize())
        {
            // 将数据移动到起始位置
            uint64_t rsz = ReadAbleSize();                            // 把当前数据⼤⼩先保存起来
            std::copy(ReadPosition(), ReadPosition() + rsz, Begin()); // 把可读数据拷⻉到起始位置
            _reader_idx = 0;                                          // 将读偏移归0
            _writer_idx = rsz;                                        // 将写位置置为可读数据⼤⼩， 因为当前的可读数据⼤⼩就是写偏移量
        }
        else
        {
            // 总体空间不够，则需要扩容，不移动数据，直接给写偏移之后扩容⾜够空间即可
            LOG(DEBUG, "正在扩容 %ld", _writer_idx + len);
            _buffer.resize(_writer_idx + len);
        }
    }
    void WriteBuffer(Buffer &data)
    {
        return Write(data.ReadPosition(), data.ReadAbleSize());
    }
    // 读取数据
    void Read(void *buf, uint64_t len)
    {
        // 要求要获取的数据⼤⼩必须⼩于可读数据⼤⼩
        assert(len <= ReadAbleSize());
        std::copy(ReadPosition(), ReadPosition() + len, (char *)buf);
    }
    std::string ReadAsString(uint64_t len)
    {
        // 要求要获取的数据⼤⼩必须⼩于可读数据⼤⼩
        assert(len <= ReadAbleSize());
        std::string str;
        str.resize(len);
        Read(&str[0], len);
        return str;
    }

public:
    Buffer() : _reader_idx(0), _writer_idx(0), _buffer(BUFFER_DEFAULT_SIZE)
    {
    }
    char *Begin()
    {
        return &*_buffer.begin();
    }
    // 获取当前写⼊起始地址, _buffer的空间起始地址，加上写偏移量
    char *WritePosition()
    {
        return Begin() + _writer_idx;
    }
    // 获取当前读取起始地址
    char *ReadPosition()
    {
        return Begin() + _reader_idx;
    }
    // 获取缓冲区末尾空闲空间⼤⼩--写偏移之后的空闲空间, 总体空间⼤⼩减去写偏移
    uint64_t TailIdleSize()
    {
        return _buffer.size() - _writer_idx;
    }
    // 获取缓冲区起始空闲空间⼤⼩--读偏移之前的空闲空间
    uint64_t HeadIdleSize()
    {
        return _reader_idx;
    }
    // 获取可读数据⼤⼩ = 写偏移 - 读偏移
    uint64_t ReadAbleSize()
    {
        return _writer_idx - _reader_idx;
    }
    // 将读偏移向后移动
    void MoveReadOffset(uint64_t len)
    {
        if (len == 0)
            return;
        // 向后移动的⼤⼩，必须⼩于可读数据⼤⼩
        assert(len <= ReadAbleSize());
        _reader_idx += len;
    }
    // 将写偏移向后移动
    void MoveWriteOffset(uint64_t len)
    {
        // 向后移动的⼤⼩，必须⼩于当前后边的空闲空间⼤⼩
        assert(len <= TailIdleSize());
        _writer_idx += len;
    }
    // 写⼊数据
    void Write(const void *data, uint64_t len)
    {
        // 1. 保证有⾜够空间，2. 拷⻉数据进去
        if (len == 0)
            return;
        EnsureWriteSpace(len);
        const char *d = (const char *)data;
        std::copy(d, d + len, WritePosition());
    }
    // 写入数据并且让写入位置同步移动
    void WriteAndPush(const void *data, uint64_t len)
    {
        Write(data, len);
        MoveWriteOffset(len);
    }
    // 写入string字符串风格数据,且让写入位置同步移动
    void WriteStringAndPush(const std::string &data)
    {
        WriteString(data);
        MoveWriteOffset(data.size());
    }
    void WriteBufferAndPush(Buffer &data)
    {
        WriteBuffer(data);
        MoveWriteOffset(data.ReadAbleSize());
    }
    // 读取数据并同步移动读位置指针
    void ReadAndPop(void *buf, uint64_t len)
    {
        Read(buf, len);
        MoveReadOffset(len);
    }
    std::string ReadAsStringAndPop(uint64_t len)
    {
        assert(len <= ReadAbleSize());
        std::string str = ReadAsString(len);
        MoveReadOffset(len);
        return str;
    }
    // 获取一行缓冲区数据
    std::string GetLineData()
    {
        char *pos = FindCRLF();
        if (pos == NULL)
        {
            return "";
        }
        // +1是为了把换⾏字符也取出来。
        return ReadAsString(pos - ReadPosition() + 1);
    }
    std::string GetLineAndPop()
    {
        std::string str = GetLineData();
        MoveReadOffset(str.size());
        return str;
    }
    // 清空缓冲区
    void Clear()
    {
        // 只需要将偏移量归0即可
        _reader_idx = 0;
        _writer_idx = 0;
    }
};
/*-----------------------------------------------------------------------------*/
#define MAX_LISTEN_BACKLOG 1024

class TcpSocket
{
private:
    bool CreateSocket()
    {
        _sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
        if (_sockfd < 0)
        {
            LOG(FATAL, "创建套接字失败!\n");
            return false;
        }
        LOG(DEBUG, "创建套接字成功!,sockfd = %d\n", _sockfd);
        return true;
    }
    // 设置描述符非阻塞
    void SetFdNoBlock(int fd)
    {
        // 先获取描述符状态
        int flag = ::fcntl(fd, F_GETFL);
        // 设置非阻塞
        ::fcntl(fd, F_SETFL, flag | O_NONBLOCK);
    }
    bool BindSocket(uint16_t port)
    {
        struct sockaddr_in peer;
        memset(&peer, 0, sizeof(peer));
        peer.sin_family = AF_INET;
        peer.sin_addr.s_addr = INADDR_ANY;
        peer.sin_port = ::htons(port);
        if (::bind(_sockfd, (struct sockaddr *)&peer, sizeof(peer)) < 0)
        {
            LOG(FATAL, "bind error!\n");
            return false;
        }
        LOG(DEBUG, "bind success!\n");
        return true;
    }
    // ip地址复用
    void RetryAddress()
    {
        int opt = 1;
        ::setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt);
        opt = 1;
        ::setsockopt(_sockfd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(int));
        LOG(DEBUG, "设置tcp套接字非阻塞完毕!\n");
    }
    bool ListenSocket(int block = MAX_LISTEN_BACKLOG)
    {
        // 监听连接请求
        if (::listen(_sockfd, block) < 0)
        {
            LOG(FATAL, "listen error!\n");
            return false;
        }
        LOG(DEBUG, "listen succss!\n");
        return true;
    }

public:
    TcpSocket() : _sockfd(-1)
    {
    }
    TcpSocket(int sockfd) : _sockfd(sockfd)
    {
        SetFdNoBlock(_sockfd);
    }
    ~TcpSocket()
    {
        if (_sockfd > 0)
        {
            ::close(_sockfd);
        }
    }
    int SockFd()
    {
        return _sockfd;
    }
    int AcceptSocket()
    {
        // 不关心client具体ip
        int sockfd = ::accept(_sockfd, nullptr, nullptr);
        if (sockfd < 0)
        {
            LOG(ERROR, "获取新连接异常!\n");
            return -1;
        }
        return sockfd;
    }
    bool Connect(const std::string &serverip, uint16_t port) // 客户端
    {
        struct sockaddr_in server; // 发送给谁？？ server！！
        memset(&server, 0, sizeof(server));
        // 填充servrip && port
        server.sin_family = AF_INET;
        // server.sin_addr.s_addr = inet_addr(serverip.c_str());
        if (::inet_pton(AF_INET, serverip.c_str(), &server.sin_addr) != 1)
        {
            LOG(ERROR, "ip地址无效!\n");
            return false;
        }
        server.sin_port = ::htons(port);
        int n = ::connect(_sockfd, (struct sockaddr *)&server, sizeof(server));
        if (n < 0)
        {
            LOG(ERROR, "连接异常!\n");
            return false;
        }
        return true;
    }
    void Close()
    {
        if (_sockfd > 0)
        {
            ::close(_sockfd);
            LOG(DEBUG, "套接字已关闭,fd = %d\n", _sockfd);
        }
    }
    bool CreateServer(uint16_t port, bool block_enable = false, int backlog = MAX_LISTEN_BACKLOG)
    {
        if (!CreateSocket())
        {
            return false;
        }
        if (block_enable)
        {
            // 如果上层设置了开启标记位就设置为非阻塞
            SetFdNoBlock(_sockfd);
        }
        if (!BindSocket(port))
        {
            return false;
        }
        if (!ListenSocket(backlog))
        {
            return false;
        }
        // 设置ip+端口地址复用
        RetryAddress();
        LOG(DEBUG, "Tcp套接字初始化完毕!\n");
        return true;
    }
    bool CreateClient(const std::string &ip, uint16_t port)
    {
        // 1. 创建套接字，2.指向连接服务器
        if (!CreateSocket())
            return false;
        if (!Connect(ip, port))
            return false;
        LOG(DEBUG, "初始化客户端套接字完毕!\n");
        return true;
    }
    ssize_t Send(const void *in, size_t len)
    {
        if (len == 0)
            return 0;
        ssize_t n = ::send(_sockfd, in, len, MSG_DONTWAIT);
        if (n < 0)
        {
            if (errno == EINTR || errno == EAGAIN)
            {
                return 0;
            }
            LOG(ERROR, "本次发送数据操作异常!,n = %d\n", n);
            return -1;
        }
        LOG(DEBUG, "发送数据完毕,发送字节:%d\n", n);
        return n;
    }
    ssize_t Recv(void *in, size_t len)
    {
        ssize_t n = ::recv(_sockfd, in, len, MSG_DONTWAIT);
        if (n < 0)
        {
            if (errno == EINTR || errno == EAGAIN)
            {
                return 0;
            }
            LOG(ERROR, "本次接收数据操作异常!,n = %d\n", n);
            return -1;
        }
        LOG(DEBUG, "接收数据完毕,接收字节:%d\n", n);
        return n;
    }

private:
    int _sockfd;
};
/*-----------------------------------------------------------------------------*/
/*Channel模块*/
class Poller;
class EventLoop;
class Channel
{
private:
    int _fd;
    EventLoop *_loop;
    uint32_t _events;  // 当前需要监控的事件
    uint32_t _revents; // 当前连接触发的事件
    using EventCallback = std::function<void()>;
    EventCallback _read_callback;  // 可读事件被触发的回调函数
    EventCallback _write_callback; // 可写事件被触发的回调函数
    EventCallback _error_callback; // 错误事件被触发的回调函数
    EventCallback _close_callback; // 连接断开事件被触发的回调函数
    EventCallback _event_callback; // 任意事件被触发的回调函数
public:
    Channel(EventLoop *loop, int fd)
        : _fd(fd),
          _events(0),
          _revents(0),
          _loop(loop)
    {
    }
    // 移除监控
    void Remove();
    void Update();
    int Fd()
    {
        return _fd;
    }
    // 获取想要监控的事件
    uint32_t Events()
    {
        return _events;
    }
    void SetREvents(uint32_t revents)
    {
        _revents = revents;
    } // 设置实际就绪的事件
    void SetReadCallback(const EventCallback &cb)
    {
        _read_callback = cb;
    }
    void SetWriteCallback(const EventCallback &cb)
    {
        _write_callback = cb;
    }
    void SetErrorCallback(const EventCallback &cb)
    {
        _error_callback = cb;
    }
    void SetCloseCallback(const EventCallback &cb)
    {
        _close_callback = cb;
    }
    void SetEventCallback(const EventCallback &cb)
    {
        _event_callback = cb;
    }
    // 当前是否监控了可读
    bool ReadEnable()
    {
        return (_events & EPOLLIN);
    }
    // 当前是否监控了可写
    bool WritEnable()
    {
        return (_events & EPOLLOUT);
    }
    // 启动读事件监控
    void OpenReadEventMonitoring()
    {
        _events |= EPOLLIN;
        Update();
    }
    // 启动写事件监控
    void OpenWriteEventMonitoring()
    {
        _events |= EPOLLOUT;
        Update();
    }
    // 关闭读事件监控
    void CloseReadEventMonitoring()
    {
        _events &= ~EPOLLIN;
        Update();
    }
    // 关闭写事件监控
    void CloseWriteEventMonitoring()
    {
        _events &= ~EPOLLOUT;
        Update();
    }
    // 关闭所有事件监控
    void CloseAllEventMonitoring()
    {
        _events = 0;
        Update();
    }
    // 事件处理，⼀旦连接触发了事件，就调⽤这个函数，根据回调的设置来处理
    void HandleEvent()
    {
        if ((_revents & EPOLLIN) || (_revents & EPOLLRDHUP) || (_revents & EPOLLPRI))
        {
            // 都看作读事件就绪!调用读回调函数处理
            if (_read_callback)
            {
                LOG(DEBUG, "描述符 %d 触发读事件,正在执行对应回调函数!\n", _fd);
                _read_callback();
            }
        }

        if (_revents & EPOLLOUT)
        {
            if (_write_callback)
            {
                LOG(DEBUG, "描述符 %d 触发写事件,正在执行对应回调函数!\n", _fd);
                _write_callback();
            }
        }
        else if (_revents & EPOLLERR)
        {
            if (_error_callback)
            {
                LOG(DEBUG, "描述符 %d 触发异常事件,正在执行对应回调函数!\n", _fd);
                _error_callback();
            }
        }
        else if (_revents & EPOLLHUP)
        {
            if (_close_callback)
            {
                LOG(DEBUG, "描述符 %d 触发连接关闭事件,正在执行对应回调函数!\n", _fd);
                _close_callback();
            }
        }
        if (_event_callback)
        {
            LOG(DEBUG, "描述符 %d 触发任意事件,正在执行对应回调函数!\n", _fd);
            _event_callback();
        }
    }
};
/*-----------------------------------------------------------------------------*/
#define MAX_EPOLL_EVENTS_DEFAULT 1024
class Poller
{
private:
    int _epfd;
    struct epoll_event _evs[MAX_EPOLL_EVENTS_DEFAULT];
    std::unordered_map<int, Channel *> _channels; // 映射表
private:
    void Update(Channel *channel, int op)
    {
        // 谁要修改监控的事件? channel!
        int fd = channel->Fd();
        struct epoll_event event;
        event.data.fd = fd;
        event.events = channel->Events();
        int n = ::epoll_ctl(_epfd, op, fd, &event);
        if (n < 0)
        {
            LOG(ERROR, "修改epoll异常!\n");
            return;
        }
        return;
    }
    // 判断channel是否被监控
    bool HasChannel(int fd)
    {
        auto iter = _channels.find(fd);
        if (iter == _channels.end())
        {
            return false;
        }
        return true;
    }

public:
    Poller()
    {
        _epfd = ::epoll_create(MAX_EPOLL_EVENTS_DEFAULT);
        if (_epfd < 0)
        {
            LOG(FATAL, "创建epoll异常!\n");
            abort();
        }
        LOG(DEBUG, "创建eoll完毕!\n");
    }
    // 增加否则修改
    void UpdateEvent(Channel *channel)
    {
        if (!HasChannel(channel->Fd()))
        {
            // 增加本次监控
            _channels.insert(std::make_pair(channel->Fd(), channel));
            return Update(channel, EPOLL_CTL_ADD);
        }
        else
        {
            // 本次为修改已存在的事件监控
            return Update(channel, EPOLL_CTL_MOD);
        }
    }
    // 移除该channel的事件监控
    void RemoveEvent(Channel *channel)
    {
        auto iter = _channels.find(channel->Fd());
        if (iter != _channels.end())
        {
            _channels.erase(iter);
        }
        Update(channel, EPOLL_CTL_DEL);
    }
    void Poll(std::vector<Channel *> *active)
    {
        LOG(DEBUG, "开始监控!\n");
        // 开始监控
        int nfds = ::epoll_wait(_epfd, _evs, MAX_EPOLL_EVENTS_DEFAULT, -1); // TODO
        if (nfds < 0)
        {
            if (errno == EINTR)
                return;
            LOG(ERROR, "epoll_wait异常!\n");
            abort();
        }
        LOG(DEBUG, "%d个描述符就绪!,fd = %d\n", nfds, _evs[0].data.fd);
        for (int i = 0; i < nfds; i++)
        {
            int fd = _evs[i].data.fd;
            uint32_t revents = _evs[i].events;
            auto iter = _channels.find(fd);
            iter->second->SetREvents(revents);
            active->push_back(iter->second);
        }
        return;
    }
};
/*-----------------------------------------------------------------------------*/
class EventLoop;
using Run_cb = std::function<void()>;
using Release_cb = std::function<void()>;
class TimerTask
{
private:
    // 任务id
    uint64_t _id;
    bool _iscancel;
    // 超时时间
    int _timeout;
    // 运行任务
    Run_cb _run_task;
    // 取消任务
    Release_cb _release_task;

public:
    TimerTask(uint64_t id, int timeout) : _id(id), _iscancel(false), _timeout(timeout)
    {
    }
    void SetRunTaskCallBack(const Run_cb &run_cb)
    {
        _run_task = run_cb;
    }
    void SetReleaseCallBack(const Release_cb &release_cb)
    {
        _release_task = release_cb;
    }
    void CancelEnable(bool flag)
    {
        _iscancel = flag;
    }
    ~TimerTask()
    {
        if (_release_task)
        {
            _release_task();
        }
        if (!_iscancel && _run_task)
        {
            _run_task();
        }
    }
    uint64_t Id()
    {
        return _id;
    }
    int Timeout()
    {
        return _timeout;
    }
};

#define MAX_TIMEOUT 60
class TimerWheel
{
public:
    using WeakPtr = std::weak_ptr<TimerTask>; // 解决循环引用问题
    using TaskrPtr = std::shared_ptr<TimerTask>;
    using Bucket = std::vector<TaskrPtr>;
    using BucketList = std::vector<Bucket>;

private:
    // 时间轮对象
    BucketList _timerWheel;
    EventLoop *_loop;
    // 为时间轮分配的channel管理事件
    std::unique_ptr<Channel> _channel_timer;
    // 秒针
    int _click;
    // 刻度
    int _capacity;
    int _timerfd;
    // 任务映射表
    std::unordered_map<uint64_t, WeakPtr> _timerTask_map;

private:
    static int CreateTimerfd()
    {
        int timerfd = ::timerfd_create(CLOCK_MONOTONIC, 0);
        if (timerfd < 0)
        {
            LOG(FATAL, "创建定时器异常\n");
            abort();
        }
        struct itimerspec new_settimer;
        new_settimer.it_interval.tv_sec = 1;
        new_settimer.it_interval.tv_nsec = 0;
        // 设置第一次超时时间
        new_settimer.it_value.tv_sec = 1;
        new_settimer.it_value.tv_nsec = 0;
        int ret = timerfd_settime(timerfd, 0, &new_settimer, nullptr);
        if (ret < 0)
        {
            LOG(ERROR, "设置超时时间异常!\n");
            abort();
        }
        LOG(DEBUG, "初始化定时器完毕!\n");
        return timerfd;
    }
    uint64_t GetTimeoutCounts()
    {
        uint64_t val = 0;
        // sleep(3);测试超时次数
        ssize_t n = ::read(_timerfd, &val, sizeof(val));
        if (n < 0)
        {
            LOG(ERROR, "获取超时次数异常!\n");
            abort();
        }
        LOG(DEBUG, "读取定时器完毕!,超时次数:%d\n", val);
        return val;
    }

public:
    TimerWheel(EventLoop *loop, int max_time_scale = MAX_TIMEOUT)
        : _timerWheel(max_time_scale),
          _loop(loop),
          _click(0),
          _capacity(max_time_scale)
    {
        _timerfd = CreateTimerfd();
        // 为时间轮分配一个Channel，监控其的读事件
        _channel_timer = std::make_unique<Channel>(_loop, _timerfd);

        // 启动读事件监控
        _channel_timer->SetReadCallback(std::bind(&TimerWheel::Start, this));
        _channel_timer->OpenReadEventMonitoring();
    }
    ~TimerWheel()
    {
    }
    bool HasTask(uint64_t id)
    {
        auto iter = _timerTask_map.find(id);
        if (iter == _timerTask_map.end())
        {
            return false;
        }
        return true;
    }
    // 在一个loop循环中处理添加任务
    void AddTaskToTimerWheelInLoop(const Run_cb &run_cb, int timeout, uint64_t id);
    // 刷新/延迟定时任务
    void RefreshTaskInLoop(uint64_t id);
    // 取消任务
    void CancelTaskInLoop(uint64_t id);

private:
    // 执行超时任务
    void Start()
    {
        int counts = GetTimeoutCounts();
        for (int i = 0; i < counts; i++)
        {
            RunTimerWheel();
        }
    }
    // 添加任务
    void TimerTaskAdd(const Run_cb &run_cb, int timeout, uint64_t id)
    {
        if (timeout > 60 || timeout <= 0)
        {
            LOG(ERROR, "超时时间允许范围[1,60],你的timeout为: %d\n", timeout);
            return;
        }
        TaskrPtr newobj = std::make_shared<TimerTask>(id, timeout);
        newobj->SetRunTaskCallBack(run_cb);
        newobj->SetReleaseCallBack(std::bind(&TimerWheel::RemoveTask, this, id));
        // 添加进映射表
        _timerTask_map[id] = WeakPtr(newobj);
        // 设置秒针位置
        _timerWheel[(_click + timeout) % _capacity].push_back(newobj);
    }
    // 删除任务
    void RemoveTask(uint64_t id)
    {
        auto iter = _timerTask_map.find(id);
        if (iter != _timerTask_map.end())
        {
            _timerTask_map.erase(iter);
        }
    }
    // 刷新任务
    void RefreshTimeTask(uint64_t id)
    {
        auto iter = _timerTask_map.find(id);
        assert(iter != _timerTask_map.end());
        int timeout = iter->second.lock()->Timeout();
        _timerWheel[(_click + timeout) % _capacity].push_back(TaskrPtr(iter->second));
    }
    // 运行时间轮
    void RunTimerWheel()
    {
        _click = (_click + 1) % _capacity;
        _timerWheel[_click].clear();
    }
    // 取消任务
    void CancelTask(uint64_t id)
    {
        auto iter = _timerTask_map.find(id);
        if (iter == _timerTask_map.end())
            return;
        TaskrPtr objptr = iter->second.lock();
        if (objptr)
            objptr->CancelEnable(true);
    }
};
/*-----------------------------------------------------------------------------*/
class EventLoop
{
private:
    using Task_t = std::function<void()>;
    using Functor = std::function<void()>;
    std::thread::id _thread_id; // 线程ID
    int _event_fd;              // eventfd唤醒IO事件监控有可能导致的阻塞
    std::unique_ptr<Channel> _event_channel;
    Poller _poller;              // 进⾏所有描述符的事件监控
    std::vector<Functor> _tasks; // 任务池
    std::mutex _mutex;           // 实现任务池操作的线程安全
    TimerWheel _timer_wheel;     // 定时器模块
public:
    // 执⾏任务池中的所有任务
    void RunAllTask()
    {
        LOG(DEBUG, "开始执行任务池中的任务,数量：%d\n", _tasks.size());
        std::vector<Functor> functor;
        {
            std::unique_lock<std::mutex> _lock(_mutex);
            _tasks.swap(functor);
        }
        // 交换任务直接执行，避免长时间阻塞!
        for (auto &task : functor)
        {
            task();
        }
        return;
    }
    static int CreateEventFd()
    {
        LOG(DEBUG, "创建eventfd完毕!\n");
        int efd = ::eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
        if (efd < 0)
        {
            LOG(ERROR, "EventLoop中创建eventfd异常!\n");
            abort(); // 让程序异常退出
        }
        LOG(DEBUG, "创建eventfd完毕,fd = %d\n", efd);
        return efd;
    }
    void ReadEventfd()
    {
        LOG(DEBUG, "向eventfd写入数据完毕!\n");
        uint64_t res = 0;
        int ret = read(_event_fd, &res, sizeof(res));
        if (ret < 0)
        {
            // EINTR -- 被信号打断； EAGAIN -- 表⽰⽆数据可读
            if (errno == EINTR || errno == EAGAIN)
            {
                return;
            }
            LOG(ERROR, "EventLoop向eventfd读取数据异常!\n");
            abort();
        }
        return;
    }
    void WeakUpEventFd()
    {
        LOG(DEBUG, "对eventfd读取数据完毕!\n");
        uint64_t val = 1;
        int ret = write(_event_fd, &val, sizeof(val));
        if (ret < 0)
        {
            if (errno == EINTR)
            {
                return;
            }
            LOG(ERROR, "EventLoop向eventfd写入数据异常!\n");
            abort();
        }
        return;
    }

public:
    EventLoop() : _thread_id(std::this_thread::get_id()),
                  _event_fd(CreateEventFd()),
                  _event_channel(new Channel(this, _event_fd)),
                  _timer_wheel(this)
    {
        // 给eventfd添加可读事件回调函数，读取eventfd事件通知次数
        LOG(DEBUG, "eventLoop---关联的线程id = %u\n", _thread_id);
        _event_channel->SetReadCallback(std::bind(&EventLoop::ReadEventfd, this));
        // 启动eventfd的读事件监控
        _event_channel->OpenReadEventMonitoring();
    }
    // 三步⾛--事件监控-》就绪事件处理-》执⾏任务
    void Start()
    {
        while (true)
        {
            // 1. 事件监控，
            std::vector<Channel *> actives;
            _poller.Poll(&actives);
            // 2. 事件处理。
            for (auto &channel : actives)
            {
                channel->HandleEvent();
            }
            // 3. 执⾏任务
            RunAllTask();
        }
    }
    // ⽤于判断当前线程是否是EventLoop对应的线程；
    bool IsInLoop()
    {
        // 注意！！线程池分配的eventLoop并不一定是一一对应的，有可能其他线程分配不对应的eventloop对象！！
        return (_thread_id == std::this_thread::get_id());
    }
    void AssertInLoop()
    {
        assert(_thread_id == std::this_thread::get_id());
    }
    // 判断将要执⾏的任务是否处于当前线程中，如果是则执⾏，不是则压⼊队列。
    void RunInLoop(const Functor &cb)
    {
        if (IsInLoop())
        {
            return cb();
        }
        // LOG(DEBUG,"当前线程id = %u,压入队列的线程id:%u\n",_thread_id,std::this_thread::get_id());
        return QueueInLoop(cb);
    }
    // 将操作压⼊任务池
    void QueueInLoop(const Functor &cb)
    {
        {
            std::unique_lock<std::mutex> _lock(_mutex);
            _tasks.push_back(cb);
        }
        // 唤醒有可能因为没有事件就绪，⽽导致的epoll阻塞；
        // 其实就是给eventfd写⼊⼀个数据，eventfd就会触发可读事件
        WeakUpEventFd();
    }
    // 添加/修改描述符的事件监控
    void UpdateEvent(Channel *channel)
    {
        return _poller.UpdateEvent(channel);
    }
    // 移除描述符的监控
    void RemoveEvent(Channel *channel)
    {
        return _poller.RemoveEvent(channel);
    }
    void TimerAdd(uint64_t id, uint32_t timeout, const Task_t &cb)
    {
        return _timer_wheel.AddTaskToTimerWheelInLoop(cb, timeout, id);
    }
    void TimerRefresh(uint64_t id)
    {
        return _timer_wheel.RefreshTaskInLoop(id);
    }
    void TimerCancel(uint64_t id)
    {
        return _timer_wheel.CancelTaskInLoop(id);
    }
    bool HasTimer(uint64_t id)
    {
        return _timer_wheel.HasTask(id);
    }
};
void Channel::Remove()
{
    _loop->RemoveEvent(this);
}
void Channel::Update()
{
    _loop->UpdateEvent(this);
}

// 在一个loop循环中处理添加任务
void TimerWheel::AddTaskToTimerWheelInLoop(const Run_cb &run_cb, int timeout, uint64_t id)
{
    _loop->RunInLoop(std::bind(&TimerWheel::TimerTaskAdd, this, run_cb, timeout, id));
}
// 刷新/延迟定时任务
void TimerWheel::RefreshTaskInLoop(uint64_t id)
{
    return _loop->RunInLoop(std::bind(&TimerWheel::RefreshTimeTask, this, id));
}
void TimerWheel::CancelTaskInLoop(uint64_t id)
{
    return _loop->RunInLoop(std::bind(&TimerWheel::CancelTask, this, id));
}
/*-----------------------------------------------------------------------------*/
class LoopThread
{
private:
    std::thread _thread;
    std::mutex _mtx;
    EventLoop *_loop;
    std::condition_variable _con;

private:
    void ThreadLoopEntry()
    {
        EventLoop loop;
        {
            std::unique_lock<std::mutex> lock(_mtx);
            _loop = &loop;
            _con.notify_all();
        }
        loop.Start();
    }

public:
    LoopThread() : _thread(std::bind(&LoopThread::ThreadLoopEntry, this)), _loop(nullptr)
    {
    }
    EventLoop *GetEventLoopPtr()
    {
        EventLoop *loop = nullptr;
        {
            std::unique_lock<std::mutex> lock(_mtx);
            if (_loop == nullptr)
            {
                _con.wait(lock, [&]()
                          { return _loop != nullptr; });
                loop = _loop;
            }
        }
        return loop;
    }
};
class LoopThreadPool
{
private:
    int _thread_nums; // 多少个线程 ?
    int _index;       // 分配出去的eventLoop的指针数组下标
    EventLoop *_base_loop;
    std::vector<LoopThread *> _threads;
    std::vector<EventLoop *> _loops;

public:
    LoopThreadPool(EventLoop *baseloop)
        : _base_loop(baseloop),
          _thread_nums(0),
          _index(0)
    {
    }
    void SetThreadNums(int num)
    {
        _thread_nums = num;
    }
    // 初始化并创建threadpool
    void Init()
    {
        if (_thread_nums > 0)
        {
            _threads.resize(_thread_nums);
            _loops.resize(_thread_nums);
            for (int i = 0; i < _thread_nums; i++)
            {
                _threads[i] = new LoopThread();
                _loops[i] = _threads[i]->GetEventLoopPtr();
            }
        }
        return;
    }
    // 分配eventLoop
    EventLoop *Dispatch()
    {
        if (_thread_nums == 0)
        {
            return _base_loop;
        }
        _index = (_index + 1) % _thread_nums;
        LOG(DEBUG, "分配的eventLoop为: %p,_index = %d\n", _loops[_index], _index);
        return _loops[_index];
    }
};

/*-----------------------------------------------------------------------------*/
// Connection连接管理模块
#define MAX_BUFFER_SIZE 65530
typedef enum
{
    DISCONNECTED,
    CONNECTING,
    CONNECTED,
    DISCONNECTING
} ConnectionStatu;
class Connection;
using ConnectionPtr = std::shared_ptr<Connection>;
class Connection : public std::enable_shared_from_this<Connection>
{
private:
    // 一个连接应该有的成员
    uint64_t _con_id;               // 连接标识符
    Channel _channel;               // 事件监控
    int _sockfd;                    // 套接字fd
    ConnectionStatu _statu;         // 连接的状态
    TcpSocket _socket;              // 收发数据的套接字
    Buffer _send_buffer;            // 发送缓冲区
    Buffer _recv_buffer;            // 接收缓冲区
    EventLoop *_loop;               // 事件管理模块
    bool _enable_no_active_release; // 是否开启非活跃链接销毁
    Any _context;                   // 用于协议切换
    using ReadEeventCallback_t = std::function<void(const ConnectionPtr &, Buffer *)>;
    using CloseServerCallback_t = std::function<void(const ConnectionPtr &)>;
    using CloseUserCallback_t = std::function<void(const ConnectionPtr &)>;
    using EventCallback_t = std::function<void(const ConnectionPtr &)>;
    using ConnectedCallback_t = std::function<void(const ConnectionPtr &)>;
    ReadEeventCallback_t _read_cb; // 处理读事件
    CloseServerCallback_t _server_close_cb;
    CloseUserCallback_t _user_close_cb;
    EventCallback_t _handle_event_cb;
    ConnectedCallback_t _connected_cb;

private:
    void HandlerRead()
    {
        char buf[MAX_BUFFER_SIZE];
        ssize_t n = _socket.Recv(buf, sizeof(buf) - 1);
        if (n < 0)
        {
            // 说明读取异常!
            return ShutdownInLoop();
        }
        _recv_buffer.WriteAndPush(buf, n);
        // 如果接收缓冲区还有可读数据
        if (_recv_buffer.ReadAbleSize() > 0 && _read_cb)
        {
            _read_cb(shared_from_this(), &_recv_buffer);
        }
        return;
    }
    void HandlerWrite()
    {
        ssize_t n = _socket.Send(_send_buffer.ReadPosition(), _send_buffer.ReadAbleSize());
        if (n < 0)
        {
            // 发送出现异常!
            if (_recv_buffer.ReadAbleSize() > 0 && _read_cb)
            {
                _read_cb(shared_from_this(), &_recv_buffer);
            }
            // 关闭连接
            return Release();
        }
        _send_buffer.MoveReadOffset(n);
        if (_send_buffer.ReadAbleSize() == 0)
        {
            // 没数据关闭写事件监控
            _channel.CloseWriteEventMonitoring();
            if (_statu == DISCONNECTING)
            {
                // 释放连接
                return Release();
            }
        }
        return;
    }
    void HandleClose()
    {
        /*⼀旦连接挂断了，套接字就什么都⼲不了了，因此有数据待处理就处理⼀下，完毕关闭连接*/
        if (_recv_buffer.ReadAbleSize() > 0)
        {
            _read_cb(shared_from_this(), &_recv_buffer);
        }
        return Release();
    }
    // 描述符异常事件处理
    void HandleError()
    {
        return HandleClose();
    }
    void CancelTaskInLoop()
    {
        _enable_no_active_release = false;
        if (_loop->HasTimer(_con_id))
            _loop->TimerCancel(_con_id);
    }
    void HandleEvent()
    {
        if (_enable_no_active_release == true)
        {
            _loop->TimerRefresh(_con_id);
        }
        if (_handle_event_cb)
        {
            _handle_event_cb(shared_from_this());
        }
    }
    // 启动非活跃连接销毁
    void EnableInactiveReleaseInLoop(int sec)
    {
        // 1. 将判断标志 _enable_inactive_release 置为true
        _enable_no_active_release = true;
        // 2. 如果当前定时销毁任务已经存在，那就刷新延迟⼀下即可
        if (_loop->HasTimer(_con_id))
        {
            return _loop->TimerRefresh(_con_id);
        }
        // 3. 如果不存在定时销毁任务，则新增
        _loop->TimerAdd(_con_id, sec, std::bind(&Connection::Release, this));
    }
    // 新连接就绪后需要初始化
    void EstablishedInLoop()
    {
        // 1. 修改连接状态； 2. 启动读事件监控； 3. 调⽤回调函数
        _statu = CONNECTED; // 当前函数执⾏完毕，则连接进⼊已完成连接状态
        // ⼀旦启动读事件监控就有可能会⽴即触发读事件，如果这时候启动了⾮活跃连接销毁
        _channel.OpenReadEventMonitoring();
        if (_connected_cb)
        {
            _connected_cb(shared_from_this());
        }
    }

    void SendInLoop(Buffer &buf)
    {
        if (_statu == DISCONNECTED)
            return;
        _send_buffer.WriteBufferAndPush(buf);
        if (!_channel.WritEnable())
        {
            _channel.OpenWriteEventMonitoring();
        }
    }
    void ReleaseInLoop()
    {
        _statu = DISCONNECTED;
        _channel.CloseAllEventMonitoring();
        _socket.Close();
        CancelTaskInLoop();
        if (_user_close_cb)
            _user_close_cb(shared_from_this());
        if (_server_close_cb)
            _server_close_cb(shared_from_this());
    }
    void ShutdownInLoop()
    {
        _statu = DISCONNECTING;
        if (_recv_buffer.ReadAbleSize() > 0)
            _read_cb(shared_from_this(), &_recv_buffer);

        if (_send_buffer.ReadAbleSize() > 0)
        {
            if (!_channel.WritEnable())
            {
                _channel.OpenWriteEventMonitoring();
            }
        }
        if (_send_buffer.ReadAbleSize() == 0)
        {
            // 不能直接执行Release！！要放入队列中!
            //  ReleaseInLoop();
            Release();
        }
        return;
    }
    void UpgradeInLoop(const Any &context,
                       const ConnectedCallback_t &conn,
                       const ReadEeventCallback_t &msg,
                       const CloseUserCallback_t &closed,
                       const EventCallback_t &event)
    {
        _context = context;
        _connected_cb = conn;
        _read_cb = msg;
        _user_close_cb = closed;
        _handle_event_cb = event;
    }

public:
    Connection(uint64_t conid, int sockfd, EventLoop *loop)
        : _con_id(conid),
          _sockfd(sockfd),
          _socket(sockfd),
          _statu(CONNECTING),
          _channel(loop, sockfd),
          _loop(loop)
    {
        _channel.SetCloseCallback(std::bind(&Connection::HandleClose, this));
        _channel.SetEventCallback(std::bind(&Connection::HandleEvent, this));
        _channel.SetReadCallback(std::bind(&Connection::HandlerRead, this));
        _channel.SetWriteCallback(std::bind(&Connection::HandlerWrite, this));
        _channel.SetErrorCallback(std::bind(&Connection::HandleError, this));
    }
    ~Connection() {}

    int Fd()
    {
        return _sockfd;
    }
    // 获取连接ID
    int Id()
    {
        return _con_id;
    }
    // 是否处于CONNECTED状态
    bool IsConnected()
    {
        return (_statu == CONNECTED);
    }
    // 设置上下⽂--连接建⽴完成时进⾏调⽤
    void SetContext(const Any &context)
    {
        _context = context;
    }
    // 获取上下⽂，返回的是指针
    Any *GetContext()
    {
        return &_context;
    }
    void SetConnectedCallback(const ConnectedCallback_t &cb)
    {
        _connected_cb = cb;
    }
    void SetMessageCallback(const ReadEeventCallback_t &cb)
    {
        _read_cb = cb;
    }
    void SetClosedCallback(const CloseUserCallback_t &cb)
    {
        _user_close_cb = cb;
    }
    void SetAnyEventCallback(const EventCallback_t &cb)
    {
        _handle_event_cb = cb;
    }
    void SetSrvClosedCallback(const CloseServerCallback_t &cb)
    {
        _server_close_cb = cb;
    }
    // 连接建⽴就绪后，进⾏channel回调设置，启动读监控，调⽤_connected_callback
    void Established()
    {
        _loop->RunInLoop(std::bind(&Connection::EstablishedInLoop, this));
    }
    // 发送数据，将数据放到发送缓冲区，启动写事件监控
    void Send(const char *data, size_t len)
    {
        // 外界传⼊的data，可能是个临时的空间，我们现在只是把发送操作压⼊了任务池，有可能并没有被⽴即执⾏
        // 因此有可能执⾏的时候，data指向的空间有可能已经被释放了。
        Buffer buf;
        buf.WriteAndPush(data, len);
        _loop->RunInLoop(std::bind(&Connection::SendInLoop, this, std::move(buf)));
    }
    // 提供给组件使⽤者的关闭接⼝--并不实际关闭，需要判断有没有数据待处理
    void Shutdown()
    {
        _loop->RunInLoop(std::bind(&Connection::ShutdownInLoop, this));
    }
    void Release()
    {
        _loop->QueueInLoop(std::bind(&Connection::ReleaseInLoop, this));
    }
    // 启动⾮活跃销毁，并定义多⻓时间⽆通信就是⾮活跃，添加定时任务
    void EnableInactiveRelease(int sec)
    {
        _loop->RunInLoop(std::bind(&Connection::EnableInactiveReleaseInLoop, this, sec));
    }
    // 取消⾮活跃销毁
    void CancelInactiveRelease()
    {
        _loop->RunInLoop(std::bind(&Connection::CancelInactiveRelease, this));
    }
    // 切换协议---重置上下⽂以及阶段性回调处理函数 -- ⽽是这个接⼝必须在EventLoop线程中⽴即执⾏
    // 防备新的事件触发后，处理的时候，切换任务还没有被执⾏--会导致数据使⽤原协议处理了。
    void Upgrade(const Any &context, const ConnectedCallback_t &conn, const ReadEeventCallback_t &msg,
                 const CloseUserCallback_t &closed, const EventCallback_t &event)
    {
        _loop->AssertInLoop();
        _loop->RunInLoop(std::bind(&Connection::UpgradeInLoop, this, context, conn, msg, closed, event));
    }
};

class Acceptor
{
private:
    TcpSocket _socket; // ⽤于创建监听套接字
    EventLoop *_loop;  // ⽤于对监听套接字进⾏事件监控
    Channel _channel;  // ⽤于对监听套接字进⾏事件管理
    using AcceptCallback = std::function<void(int)>;
    AcceptCallback _accept_callback;

private:
    /*监听套接字的读事件回调处理函数---获取新连接，调⽤_accept_callback函数进⾏新连
   接处理*/
    void HandleRead()
    {
        int newfd = _socket.AcceptSocket();
        if (newfd < 0)
        {
            return;
        }
        if (_accept_callback)
        {
            _accept_callback(newfd);
        }
    }
    int CreateServer(int port)
    {
        bool ret = _socket.CreateServer(port);
        return _socket.SockFd();
    }

public:
    /*不能将启动读事件监控，放到构造函数中，必须在设置回调函数后，再去启动*/
    /*否则有可能造成启动监控后，⽴即有事件，处理的时候，回调函数还没设置：新连接得不
   到处理，且资源泄漏*/
    Acceptor(EventLoop *loop, uint16_t port) : _socket(CreateServer(port)),
                                               _loop(loop),
                                               _channel(loop, _socket.SockFd())
    {
        _channel.SetReadCallback(std::bind(&Acceptor::HandleRead, this));
    }
    void SetAcceptCallback(const AcceptCallback &cb)
    {
        _accept_callback = cb;
    }
    void Listen()
    {
        _channel.OpenReadEventMonitoring();
    }
};

class TcpServer
{
private:
    uint64_t _next_id; // 这是⼀个⾃动增⻓的连接ID，
    int _port;
    int _timeout;                  // 这是⾮活跃连接的超时时间---多⻓时间⽆通信就是⾮活跃连接
    bool _enable_inactive_release; // 是否启动了⾮活跃连接超时销毁的判断标志
    EventLoop _baseloop;           // 这是主线程的EventLoop对象，负责监听事件的处理
    Acceptor _acceptor;            // 这是监听套接字的管理对象
    LoopThreadPool _pool;          // 这是从属EventLoop线程池
    // 保存管理所有连接对应的shared_ptr对象
    std::unordered_map<uint64_t, ConnectionPtr> _conns;
    using ConnectedCallback = std::function<void(const ConnectionPtr &)>;
    using MessageCallback = std::function<void(const ConnectionPtr &, Buffer *)>;
    using ClosedCallback = std::function<void(const ConnectionPtr &)>;
    using AnyEventCallback = std::function<void(const ConnectionPtr &)>;
    using Functor = std::function<void()>;
    ConnectedCallback _connected_callback;
    MessageCallback _message_callback;
    ClosedCallback _closed_callback;
    AnyEventCallback _event_callback;

private:
    void RunAfterInLoop(const Functor &task, int delay)
    {
        _next_id++;
        _baseloop.TimerAdd(_next_id, delay, task);
    }
    // 为新连接构造⼀个Connection进⾏管理
    void NewConnection(int fd)
    {
        _next_id++;
        ConnectionPtr conn(new Connection(_next_id, fd, _pool.Dispatch()));
        conn->SetMessageCallback(_message_callback);
        conn->SetClosedCallback(_closed_callback);
        conn->SetConnectedCallback(_connected_callback);
        conn->SetAnyEventCallback(_event_callback);
        conn->SetSrvClosedCallback(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
        // 启动⾮活跃超时销毁
        if (_enable_inactive_release)
        {
            conn->EnableInactiveRelease(_timeout);
        }
        conn->Established(); // 就绪初始化
        _conns.insert(std::make_pair(_next_id, conn));
    }
    void RemoveConnectionInLoop(const ConnectionPtr &conn)
    {
        int id = conn->Id();
        auto it = _conns.find(id);
        if (it != _conns.end())
        {
            _conns.erase(it);
        }
    }
    // 从管理Connection的_conns中移除连接信息
    void RemoveConnection(const ConnectionPtr &conn)
    {
        _baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));
    }

public:
    TcpServer(int port) : _port(port),
                          _next_id(0),
                          _enable_inactive_release(false),
                          _acceptor(&_baseloop, port),
                          _pool(&_baseloop)
    {
        _acceptor.SetAcceptCallback(std::bind(&TcpServer::NewConnection,
                                              this, std::placeholders::_1));
        _acceptor.Listen(); // 将监听套接字挂到baseloop上
    }
    void SetThreadCount(int count)
    {
        return _pool.SetThreadNums(count);
    }
    void SetConnectedCallback(const ConnectedCallback &cb)
    {
        _connected_callback = cb;
    }
    void SetMessageCallback(const MessageCallback &cb)
    {
        _message_callback = cb;
    }
    void SetClosedCallback(const ClosedCallback &cb)
    {
        _closed_callback = cb;
    }
    void SetAnyEventCallback(const AnyEventCallback &cb)
    {
        _event_callback = cb;
    }
    void EnableInactiveRelease(int timeout)
    {
        _timeout = timeout;
        _enable_inactive_release = true;
    }
    // ⽤于添加⼀个定时任务
    void RunAfter(const Functor &task, int delay)
    {
        _baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop, this,
                                      task, delay));
    }
    void Start()
    {
        _pool.Init();
        LOG(DEBUG, "线程池初始化完毕!\n");
        _baseloop.Start();
    }
};
class NetWork
{
public:
    NetWork()
    {
        EnabelFILTRATION();
        LOG(DEBUG, "捕获SIGPIPE信号!\n");
        signal(SIGPIPE, SIG_IGN);
    }
};
static NetWork work;